﻿// <copyright file="TopListProvider.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains the TopListProvider.</summary>

namespace Sqwarea.GameLogic.TopList
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using GameLogic.Extensions;
    using Sqwarea.Persistence;

    /// <summary>
    /// Provider of the best kings list
    /// </summary>
    public class TopListProvider : ITopListProvider
    {
        /// <summary>
        /// The provider of list of best kings
        /// </summary>
        private readonly IBestKingsProvider _bestKingProvider;

        /// <summary>
        /// The provider of various information about the game
        /// </summary>
        private readonly IGameProvider _gameProvider;

        /// <summary>
        /// The provider of users
        /// </summary>
        private readonly IUserProvider _userProvider;

        /// <summary>
        /// Initializes a new instance of the TopListProvider class
        /// </summary>
        /// <param name="bestKingsProvider">Provider of the list of best kings</param>
        /// <param name="gameProvider">Provider of game information</param>
        /// <param name="userProvider">Provider for users</param>
        public TopListProvider(IBestKingsProvider bestKingsProvider, IGameProvider gameProvider, IUserProvider userProvider)
        {
            if (bestKingsProvider == null)
            {
                throw new ArgumentNullException("bestKingsProvider");
            }

            if (gameProvider == null)
            {
                throw new ArgumentNullException("gameProvider");
            }

            if (userProvider == null)
            {
                throw new ArgumentNullException("userProvider");
            }

            this._bestKingProvider = bestKingsProvider;
            this._gameProvider = gameProvider;
            this._userProvider = userProvider;
        }

        /// <summary>
        /// Reorganize the winner set and the loser set, update the best kings list via BestKingsProvider. To be called by a scheduled service.
        /// </summary>
        public void Condensation()
        {
            //// We filter out little kings here
            var list = from k in this._gameProvider.GetAllKings()
                       select k;
            
            var maxListAccumulator = new MaxListAccumulator<King>(new King(-1, string.Empty, string.Empty));

            foreach (var king in list.Where(king => !king.IsNeutral()))
            {
                maxListAccumulator.Add(king.SquaresNumber, king);
            }
            
            var toplist = maxListAccumulator.MaxList();
            this._bestKingProvider.UpdateBestKings(toplist);
        }

        /// <summary>
        /// Returns the sorted list of best kings, i.e. the top list
        /// </summary>
        /// <returns>the top list of kings</returns>
        public IEnumerable<King> GetBestKings()
        {
            return this._bestKingProvider.GetBestKings();
        }
    }
}